package com.cch.cooperation.api.common.sdk.apple;

import cn.hutool.core.bean.BeanUtil;
import com.cch.cooperation.api.common.sdk.apple.model.AppleConfig;
import com.cch.cooperation.api.common.sdk.apple.model.AppleIdTokenJwt;
import com.nimbusds.jose.JWSVerifier;
import com.nimbusds.jose.crypto.ECDSAVerifier;
import com.nimbusds.jose.crypto.RSASSAVerifier;
import com.nimbusds.jose.jwk.JWK;
import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jwt.SignedJWT;

import java.net.URL;
import java.util.Date;
import java.util.Objects;

/**
 * Apple 客户端
 *
 * @author cch
 */
public class AppleClient {

    private AppleConfig config;

    public AppleClient(AppleConfig config) {
        this.config = config;
    }

    /**
     * 验证 ID 令牌的有效性
     *
     * @param idToken ID 令牌
     * @return true 如果 ID 令牌有效，否则 false
     */
    public boolean validIdToken(String idToken) throws Exception {
        SignedJWT signedJWT = SignedJWT.parse(idToken);
        // 验证是否过期
        Date expirationTime = signedJWT.getJWTClaimsSet().getExpirationTime();
        if (expirationTime.before(new Date())) {
            return false;
        }
        // 获取 Apple 公钥并验证签名
        JWKSet jwkSet = JWKSet.load(new URL("https://appleid.apple.com/auth/keys"));
        JWK jwk = jwkSet.getKeyByKeyId(signedJWT.getHeader().getKeyID());
        if (Objects.isNull(jwk)) {
            return false;
        }
        // 验证签名
        JWSVerifier verifier = null;
        if ("RSA".equals(jwk.getKeyType().getValue())) {
            verifier = new RSASSAVerifier(jwk.toRSAKey());
        } else if ("EC".equals(jwk.getKeyType().getValue())) {
            verifier = new ECDSAVerifier(jwk.toECKey());
        }
        if (Objects.isNull(verifier)) {
            return false;
        }
        return signedJWT.verify(verifier);
    }

    /**
     * 解析 ID 令牌
     *
     * @param idToken ID 令牌
     * @return AppleIdTokenJwt 包含 ID 令牌的详细信息,解析失败返回null
     */
    public AppleIdTokenJwt parseIdToken(String idToken) throws Exception {
        // 验证 ID 令牌
        if (!validIdToken(idToken)) {
            return null;
        }
        // 解析 ID 令牌
        SignedJWT signedJWT = SignedJWT.parse(idToken);
        AppleIdTokenJwt appleIdTokenJwt = new AppleIdTokenJwt();
        BeanUtil.copyProperties(signedJWT.getPayload().toJSONObject(), appleIdTokenJwt, true);
        return appleIdTokenJwt;
    }

}
